import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.TemporalAdjusters;
import java.util.Locale;
public class DateUtil {
    static void getLocalDate() {
        LocalDateTime dt = LocalDateTime.parse("2019-05-18T13:20:29.123");
        LocalDate dt1 = LocalDate.parse("2019-06-27");
        LocalDate dt5 = dt1.minusMonths(5);
        LocalDate dt6 = dt1.withMonth(7);
        System.out.println(dt);
        System.out.println(dt1);
        System.out.println(dt5);
        System.out.println(dt6);
        LocalDate dt7 = LocalDate.now().plusMonths(1).with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
        System.out.println(dt7);

        // 自定义格式化:
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        System.out.println(dtf.format(LocalDateTime.now()));

        // 用自定义格式解析:
        LocalDateTime dt2 = LocalDateTime.parse("2019/11/30 15:16:17", dtf);
        System.out.println(dt2);
    }

    static boolean getTimeOrder(LocalDateTime src, LocalDateTime target, TimeOrder timeOrder) {
        return timeOrder == TimeOrder.isBefore ? src.isBefore(target) : src.isAfter(target);
    }
    static void getFlightCostTime() {
        LocalDateTime departureAtBeijing = LocalDateTime.of(2019, 9, 15, 13, 0, 0);
        int hours = 13;
        int minutes = 20;
        LocalDateTime arrivalAtNewYork = calculateArrivalAtNY(departureAtBeijing, hours, minutes);
        System.out.println(departureAtBeijing + " -> " + arrivalAtNewYork);
        // test:
        if (!LocalDateTime.of(2019, 10, 15, 14, 20, 0)
                .equals(calculateArrivalAtNY(LocalDateTime.of(2019, 10, 15, 13, 0, 0), 13, 20))) {
            System.err.println("测试失败!");
        } else if (!LocalDateTime.of(2019, 11, 15, 13, 20, 0)
                .equals(calculateArrivalAtNY(LocalDateTime.of(2019, 11, 15, 13, 0, 0), 13, 20))) {
            System.err.println("测试失败!");
        }
    }

    static LocalDateTime calculateArrivalAtNY(LocalDateTime bj, int h, int m) {
        LocalDateTime arrivalTime = bj.plusHours(h).plusMinutes(m);
        //附加一个zoneId转换为时区时间
        ZonedDateTime bjZoneTime = arrivalTime.atZone(ZoneId.of("Asia/Shanghai"));
        ZonedDateTime nyZoneTime = bjZoneTime.withZoneSameInstant(ZoneId.of("America/New_York"));
        return nyZoneTime.toLocalDateTime();
    }

    static void getLocalDateTimeFromTimeStamp() {
        long ts = 1574208900000L;
        System.out.println(timestampToString(ts, Locale.CHINA, "Asia/Shanghai"));
        System.out.println(timestampToString(ts, Locale.US, "America/New_York"));
    }

    static String timestampToString(long ts, Locale lo, String zoneId) {
        Instant instant = Instant.ofEpochMilli(ts);
        ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.of(zoneId));
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM, FormatStyle.SHORT);
        return dateTimeFormatter.withLocale(lo).format(zonedDateTime);
    }

    static long mutiple(long n) {
        if(n < 0) {
            throw new IllegalArgumentException();
        }
        if(n > 20) {
            throw new ArithmeticException();
        }
        long r = 1;
        for(long i = 1; i <= n; i++) {
            r = r * i;
        }
        return r;
    }

    public static String capitalize(String s) {
        if (s.isEmpty()) {
            return s;
        }
        return Character.toUpperCase(s.charAt(0)) + s.substring(1).toLowerCase();
    }

    enum TimeOrder {
        isBefore, isAfter
    }
}
